<?php
namespace app\apijson\core;

use Illuminate\Database\Capsule\Manager as DB;

class ApiJsonFactory
{
    /**
     * 统一静态入口，简化 APIJSON 查询调用
     * @param array $json
     * @param string $method
     * @return mixed
     */
    public static function query(array $json, string $method = 'get')
    {
        $configFile = __DIR__ . '/../config/Apijson.php';
        if (file_exists($configFile)) {
            $cfg = include $configFile;
            if (!empty($cfg['permission_checker'])) {
                $checker = $cfg['permission_checker'];
                if (is_callable([$checker, 'check'])) {
                    // 获取当前 request 对象（webman 全局函数）
                    $request = request()->all();
                    $checker::check($method, $json, $request);
                }
            }
        }
        try {
            $showSql = false;
            if (file_exists($configFile)) {
                $cfg = include $configFile;
                $showSql = $cfg['show_sql'] ?? false;
                // 新增敏感操作开关判断
                if ($method === 'post' && empty($cfg['allow_post'])) {
                    throw new ApiJsonException('不允许新增操作，请联系管理员开启 allow_post 配置');
                }
                if ($method === 'patch' && empty($cfg['allow_patch'])) {
                    throw new ApiJsonException('不允许修改操作，请联系管理员开启 allow_patch 配置');
                }
                if ($method === 'delete' && empty($cfg['allow_delete'])) {
                    throw new ApiJsonException('不允许删除操作，请联系管理员开启 allow_delete 配置');
                }
            }
            $sqls = [];
            if ($showSql) {
                DB::connection()->flushQueryLog();
                DB::connection()->enableQueryLog();
            }
            $service = new ApiJsonService();
            $result = $service->handle($json, $method);
            if ($showSql) {
                $sqls = DB::connection()->getQueryLog();
                // 格式化 SQL
                $sqls = array_map(function($item) {
                    $sql = $item['query'];
                    foreach ($item['bindings'] as $binding) {
                        $sql = preg_replace('/\?/', is_numeric($binding) ? $binding : "'" . $binding . "'", $sql, 1);
                    }
                    return $sql;
                }, $sqls);
                if (is_array($result)) {
                    $result['sql'] = $sqls;
                }
            }
            return $result;
        } catch (ApiJsonException $e) {
            return config('app.env') == 'production' ? exp_abort($e->getMessage()) : exp_abort($e->getFile().$e->getCode().': '.$e->getMessage());
        } catch (\Throwable $e) {
            return config('app.env') == 'production' ? exp_abort($e->getMessage()) : exp_abort($e->getFile().$e->getCode().': '.$e->getMessage());
        }
    }
} 